import lib.problem as problem
import unittest
import math

class Problem025(problem.Problem):
	def __init__(self):
		problem.Problem.__init__(self, 25)
		
	def fibonacci(self, n):
		if n < 3:
			return 1
		f1 = 1
		f2 = 1
		fibo = 0
		for _i in range(3, n + 1):
			fibo = f1 + f2
			f1 = f2
			f2 = fibo
			
			
		return fibo
	
	def fibonacciTermLargerThan(self, n):
		if n < 3:
			return 1
		f1 = 1
		f2 = 1
		fibo = 0
		i = 2
		while fibo < n:
			fibo = f1 + f2
			f1 = f2
			f2 = fibo
			i += 1
			
		return i
	
		
	def solve(self):
		n = pow(10, 999) - 1
		return self.fibonacciTermLargerThan(n)
	
	
	
class Problem025Tester(unittest.TestCase):
	
	def setUp(self):
		self.p025 = Problem025()
		
	def testFibonacci5(self):
		fibo = self.p025.fibonacci(5)
		self.assertEquals(5, fibo)
	
	def testFibonacci12(self):
		fibo = self.p025.fibonacci(12)
		self.assertEquals(144, fibo)
		
	def testFibonacciTermLargerThan100(self):
		fibo = self.p025.fibonacciTermLargerThan(100)
		self.assertEquals(12, fibo)
		
	def testFibonacciTermLargerThan10000000(self):
		fibo = self.p025.fibonacciTermLargerThan(10000000)
		self.assertEquals(36, fibo)
		
	def testFibonacciTermLargerThan10pow1000(self):
		n = pow(10, 999) - 1
		fibo = self.p025.fibonacciTermLargerThan(n)
		self.assertEquals(4782, fibo)
	
	def testSolve(self):
		self.assertEquals(4782, self.p025.solve())
		
